package com.unlcn.ils.wms.backend.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateUtils {

    /**
     * 时间格式.
     */
    public static final String FORMAT_DATE_NO_YEAR = "MM月dd日 HH:mm";

    public static final String FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";

    public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss:SSS";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String FORMAT_DATETIME_LINE = "dd/MM/yyyy HH:mm:ss";

    public static final String FORMAT_DATETIME_NO_SEPARATOR = "yyyyMMddHHmmsss";

    public static final String FORMAT_YYYYMMDD= "yyyyMMdd";

    /**
     * 获取当前时间是 星期几
     *
     * @param dt
     * @return
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /**
     * 返回比当前日期早N天的日期
     *
     * @param n 天数
     * @return 2016-01-01
     */
    public static String getbeforeDay(int n) {
        Date ndate = new Date();
        // n天共n*24*60*60*1000毫秒
        long currentdate = ndate.getTime() - n * 24 * 60 * 60 * 1000;
        Date dd = new Date(currentdate);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dt = sdf.format(dd);
        return dt;
    }

    /**
     * 返回比当前日期早七天的日期
     *
     * @return 2016-01-01
     */
    public static String getDay() {
        Date ndate = new Date();
        /** 七天共 604800000 毫秒 */
        long currentdate = ndate.getTime() - 604800000;
        Date dd = new Date(currentdate);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dt = sdf.format(dd);
        return dt;
    }

    /**
     * 获取当前日期
     *
     * @return 2016-01-01 00:00:00
     */
    public static String getCurrentDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dt = sdf.format(new Date());
        return dt;
    }

    /**
     * 获取当前日期0点
     *
     * @return 2016-01-01 00:00:00
     */
    public static String getCurrentZeroDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String dt = sdf.format(new Date());
        return dt;
    }

    /**
     * 获取当前日期0点
     *
     * @return 2016-01-01 00:00:00
     */
    public static Date getDate00ZeroDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String dt = sdf.format(date);
        return StrToDate(dt);
    }

    /**
     * 获取当前日期0点
     *
     * @return 2016-01-01 00:00:00
     */
    public static Date getCurrent00ZeroDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String dt = sdf.format(new Date());
        return StrToDate(dt);
    }

    /**
     * 获取当前日期23点
     *
     * @return 2016-01-01 23:59:59
     */
    public static Date getCurrent23ZeroDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        String dt = sdf.format(new Date());
        return StrToDate(dt);
    }

    /**
     * 获取当前日期
     *
     * @return format
     */
    public static String getCurrentZeroDate(String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String dt = sdf.format(new Date());
        return dt;
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @return date
     */
    public static Date StrToDate(String str) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 格式化字符串日期
     *
     * @param str
     * @param formatStr
     * @param str       日期字符串
     * @param formatStr 格式化字符串
     * @return date 日期对象
     */
    public static Date StrToDate(String str, String formatStr) {
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 时间戳 转为Date
     *
     * @param millTimes
     * @return
     */
    public static Date getDatetime(long millTimes) {
        String sdate = new SimpleDateFormat(FORMAT_DATETIME_LINE).format(new Date(millTimes * 1000));
        // String date = getStringFromDate(new Date(millTimes), FORMAT_DATETIME);
        SimpleDateFormat format = new SimpleDateFormat(FORMAT_DATETIME_LINE);
        Date date = null;
        try {
            date = format.parse(sdate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 将日期格式化为指定的字符串.<br>
     * <br>
     *
     * @param d      日期.
     * @param format 输出字符串格式.
     * @return 日期字符串
     */
    public static String getStringFromDate(Date d, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(d);
    }

    // 上月第一天
    public static Date firstDayOfLastMonth(Date date) throws Exception {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, -1);
        return cal.getTime();
    }

    // 上月最后一天
    public static Date firstDayOfCurrMonth(Date date) throws Exception {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);

        return cal.getTime();
    }

    /**
     * 为指定日期增加几个月
     *
     * @param date   指定日期
     * @param amount 增加的数量
     * @return 增加指定单位之间之后的Date对象
     */
    public static Date addMonths(Date date, int amount) {
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * 为指定日期增加一段指定单位的时间
     *
     * @param date          日期对象
     * @param calendarField 时间单位。
     * @param amount        数量
     * @return 增加指定单位之间之后的Date对象
     */
    private static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(calendarField, amount);
        return c.getTime();
    }

    /**
     * 获取相差时间，精确到分钟。与当前时间的时间差
     *
     * @param date
     * @return
     */
    public static Long getDiffMin(Date date) {
        Calendar dateOne = Calendar.getInstance(), dateTwo = Calendar.getInstance();
        dateOne.setTime(new Date()); // 设置为当前系统时间
        dateTwo.setTime(date);
        long timeOne = dateOne.getTimeInMillis();
        long timeTwo = dateTwo.getTimeInMillis();
        long minute = (timeOne - timeTwo) / (1000 * 60);// 转化minute
        return minute;
    }

    /**
     * 获取相差时间，精确到小时。与当前时间的时间差
     *
     * @param date
     * @return
     */
    public static long getDiffHours(Date date) {
        Calendar dateOne = Calendar.getInstance(), dateTwo = Calendar.getInstance();
        dateOne.setTime(new Date()); // 设置为当前系统时间
        dateTwo.setTime(date);
        long timeOne = dateOne.getTimeInMillis();
        long timeTwo = dateTwo.getTimeInMillis();
        long hour = (timeTwo - timeOne) / (1000 * 60 * 60);// 转化minute
        return hour;
    }

    /**
     * 当前月份第一天
     *
     * @return
     */
    public static Date getFirstDay4Month() {
        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        System.out.println(sdf.format(c.getTime()));
        try {
            return sdf.parse(sdf.format(c.getTime()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return c.getTime();
    }

    /**
     * 当前月份第一天 零点零分零秒
     *
     * @return
     */
    public static Date getFirstDay0Month() {
        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        System.out.println(sdf.format(c.getTime()));
        try {
            return sdf.parse(sdf.format(c.getTime()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return c.getTime();
    }

    /**
     * 当前月份最后一天
     *
     * @return
     */
    public static Date getLastDay4Month() {
        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return ca.getTime();
    }

    //上周一
    public static Date lastMonday(Date date) throws Exception {

        int n = -1;
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
            n = -2;
        }
        cal.add(Calendar.DATE, n * 7);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * 为指定日期增加几天
     *
     * @param date   指定日期
     * @param amount 增加的数量
     * @return 增加指定单位之间之后的Date对象
     */
    public static Date addDays(Date date, int amount) {
        return add(date, Calendar.DAY_OF_MONTH, amount);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取当前日期的星期一
     *
     * @return
     * @throws ParseException
     */
    public static Date getFirstDayOfWeek() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00", Locale.CHINA);
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        System.out.println(sdf.format(calendar.getTime()));
        return sdf.parse(sdf.format(calendar.getTime()));
    }

}
